﻿using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Volo.Abp;
using Volo.Abp.Caching;

namespace Joy.Erp.Ufida.Core
{
    public class TokenUfidaAppService : UfidaAppService, ITokenUfidaAppService
    {
        private readonly IDistributedCache<TokenDto, U9ApiConfig> _tokenCache;

        protected IU9ApiConfigService ConfigService { get; }

        public U9ApiConfig U9ApiConfig { get; set; }

        public TokenUfidaAppService(
            IU9ApiConfigService u9ApiConfigService,
            IDistributedCache<TokenDto, U9ApiConfig> tokenCache
        )
        {
            ConfigService = u9ApiConfigService;
            U9ApiConfig = ConfigService.GetDefaultConfig();
            _tokenCache = tokenCache;
        }

        public async Task<string> GetTokenAsync(U9ApiConfig config = null)
        {
            if (config == null) config = U9ApiConfig;

            var tokenDto = await _tokenCache.GetOrAddAsync(
                config,
                async () => await GetTokenFromApiAsync(config),
                () =>
                    new DistributedCacheEntryOptions
                    {
                        AbsoluteExpiration = DateTimeOffset.Now.AddHours(3),
                    }
            );

            return tokenDto.Data;
        }

        public async Task<TokenDto> GetTokenFromApiAsync(U9ApiConfig config)
        {
            var getTokenBaseUrl = U9ApiConfig.BaseUrl.AppendSegments($"webapi/OAuth2/AuthLogin");
            var getTokenUrl = getTokenBaseUrl
                .AppendParam("clientid", U9ApiConfig.ClientId)
                .AppendParam("clientsecret", U9ApiConfig.ClientSecret)
                .AppendParam("entCode", U9ApiConfig.EntCode)
                .AppendParam("userCode", U9ApiConfig.UserCode)
                .AppendParam("orgCode", U9ApiConfig.OrgCode);
            Logger.LogInformation($"开始获取Token令牌，请求URL为: {getTokenUrl}");

            var httpClinet = new HttpClient();
            var response = await httpClinet.GetAsync(getTokenUrl);
            response.HandStatusCode(getTokenBaseUrl);

            var responseContent = await response.Content.ReadAsStringAsync();
            Logger.LogInformation($"开始解析Token令牌");

            try
            {
                var tokenDto = JsonConvert.DeserializeObject<TokenDto>(responseContent);

                Logger.LogInformation($"获取Token令牌成功，令牌内容: {tokenDto.Data}");
                return tokenDto;
            }
            catch (JsonException ex)
            {
                throw new BusinessException("BasicArchives:103", innerException: ex).WithData(
                    "DtoType",
                    typeof(TokenDto).Name
                );
            }
        }
    }
}
